
-- ** Windows Native Functionality for Playing Video (DirectShow etc.) **
-- binding by Duncan Cross duncan{dot}cross{at}gmail{dot}com

local com = require 'bindings.com'
local wincommon = require 'bindings.wincommon'


module (...)


local IFilterGraph = com.IUnknown:extend{
  IID = "56a8689f-0ad4-11ce-b03a-0020af0ba770";
  name = "IFilterGraph";
  target = _M;
  {name="AddFilter"; "pointer" --[[IBaseFilter *pFilter]], "pointer" --[[LPCWSTR pName]]};
  {name="RemoveFilter"; "pointer" --[[IBaseFilter *pFilter]]};
  {name="EnumFilters"; "pointer" --[[<out> IEnumFilters **ppEnum]]};
  {name="FindFilterByName"; "pointer" --[[LPCWSTR pName]], "pointer" --[[<out> IBaseFilter **ppFilter]]};
  {name="ConnectDirect"; "pointer" --[[IPin *ppinOut]], "pointer" --[[IPin *ppinIn]], "pointer" --[[<unique> const AM_MEDIA_TYPE *pmt]]};
  {name="Reconnect"; "pointer" --[[IPin *ppin]]};
  {name="Disconnect"; "pointer" --[[IPin *ppin]]};
  {name="SetDefaultSyncSource"};
}

local IGraphBuilder = IFilterGraph:extend{
  IID = "56a868a9-0ad4-11ce-b03a-0020af0ba770";
  name = "IGraphBuilder";
  target = _M;
  {name="Connect"; "pointer" --[[IPin *ppinOut]], "pointer" --[[IPin *ppinIn]]};
  {name="Render"; "pointer" --[[IPin *ppinOut]]};
  {name="RenderFile"; "pointer" --[[LPCWSTR lpcwstrFile]], "pointer" --[[<unique> LPCWSTR lpcwstrPlayList]]};
  {name="AddSourceFilter"; "pointer" --[[LPCWSTR lpcwstrFileName]], "pointer" --[[<unique> LPCWSTR lpcwstrFilterName]],
    'pointer' --[[<out> IBaseFilter **ppFilter]]};
  {name="SetLogFile"; "ulong" --[[DWORD_PTR hFile]]};
  {name="Abort"};
  {name="ShouldOperationContinue"};
}

local IMediaFilter = com.IPersist:extend{
  IID = "56a86899-0ad4-11ce-b03a-0020af0ba770";
  name = "IMediaFilter";
  target = _M;
  {name="Stop"};
  {name="Pause"};
  {name="Run", "long" --[[REFERENCE_TIME tStart]]};
  {name="GetState", "ulong" --[[DWORD dwMilliSecsTimeout]], "pointer" --[[FILTER_STATE*]]};
  {name="SetSyncSource", "pointer" --[[IReferenceClock *pClock]]};
  {name="GetSyncSource", "pointer" --[[IReferenceClock **pClock]]};
}

local IBaseFilter = IMediaFilter:extend{
  IID = "56a86895-0ad4-11ce-b03a-0020af0ba770";
  name = "IBaseFilter";
  target = _M;
  {name="EnumPins", "pointer" --[[IEnumPins **ppEnum]]};
  {name="FindPin", "pointer" --[[LPCWSTR Id]], "pointer" --[[IPin**]]};
  {name="QueryFilterInfo", "pointer" --[[FILTER_INFO*]]};
  {name="JoinFilterGraph", "pointer" --[[IFilterGraph *pGraph]], "pointer" --[[LPCWSTR name]]};
  {name="QueryVendorInfo", "pointer" --[[LPWSTR*]]};
}

local IEnumPins = com.IUnknown:extend{
  IID = "56a86892-0ad4-11ce-b03a-0020af0ba770";
  name = "IEnumPins";
  target = _M;
  {name="Next"; "ulong" --[[cPins]], "pointer" --[[IPin**]], "pointer" --[[ULONG* pcFetches]]};
  {name="Skip"; "ulong" --[[cPins]]};
  {name="Reset"};
  {name="Clone"; "pointer" --[[IEnumPins**]]};
}

local IMediaControl = com.IDispatch:extend{
  IID = "56a868b6-0ad4-11ce-b03a-0020af0ba770";
  name = "IMediaControl";
  target = _M;
  {name="Run"};
  {name="Pause"};
  {name="Stop"};
  {name="GetState"; "long" --[[msTimeout]], "pointer" --[[OAFilterState*]]};
  {name="RenderFile"; "pointer" --[[BSTR strFilename]]};
  {name="AddSourceFilter"; "pointer" --[[BSTR strFilename]], "pointer" --[[IDispatch** ppUnk]]};
  {name="get_FilterCollection"; "pointer" --[[IDispatch** ppUnk]]};
  {name="get_RegFilterCollection"; "pointer" --[[IDispatch** ppUnk]]};
  {name="StopWhenReady"};
}

IVideoWindow = com.IDispatch:extend{
  IID = "56a868b4-0ad4-11ce-b03a-0020af0ba770";
  target = _M;
  name = "IVideoWindow";
  {name="put_Caption"; "pointer"};            {name="get_Caption"; "pointer"};              --[[BSTR]]
  {name="put_WindowStyle"; "long"};           {name="get_WindowStyle"; "pointer"};
  {name="put_WindowStyleEx"; "long"};         {name="get_WindowStyleEx"; "pointer"};
  {name="put_AutoShow"; "long"};              {name="get_AutoShow"; "pointer"};
  {name="put_WindowState"; "long"};           {name="get_WindowState"; "pointer"};
  {name="put_BackgroundPalette"; "long"};     {name="get_BackgroundPalette"; "pointer"};
  {name="put_Visible"; "long"};               {name="get_Visible"; "pointer"};
  {name="put_Left"; "long"};                  {name="get_Left"; "pointer"};
  {name="put_Width"; "long"};                 {name="get_Width"; "pointer"};
  {name="put_Top"; "long"};                   {name="get_Top"; "pointer"};
  {name="put_Height"; "long"};                {name="get_Height"; "pointer"};
  {name="put_Owner"; "long"};                 {name="get_Owner"; "pointer"};               --[[OAHWND]]
  {name="put_MessageDrain"; "long"};          {name="get_MessageDrain"; "pointer"};        --[[OAHWND]]
  {name="get_BorderColor"; "pointer"};        {name="put_BorderColor"; "long"};
  {name="get_FullScreenMode"; "pointer"};     {name="put_FullScreenMode"; "long"};
  {name="SetWindowForeground"; "long"};
  {name="NotifyOwnerMessage"; "long" --[[OAHWND]], "long" --[[uMsg]], "long" --[[wParam]], "long" --[[lParam]]};
  {name="SetWindowPosition"; "long" --[[Left]], "long" --[[Top]], "long" --[[Width]], "long" --[[Height]]};
  {name="GetWindowPosition"; "pointer" --[[long *pLeft]], "pointer" --[[long *pTop]], "pointer" --[[long *pWidth]], "pointer" --[[long *pHeight]]};
  {name="GetMinIdealImageSize"; "pointer" --[[long *pWidth]], "pointer" --[[long *pHeight]]};
  {name="GetMaxIdealImageSize"; "pointer" --[[long *pWidth]], "pointer" --[[long *pHeight]]};
  {name="GetRestoreCulture"; "pointer" --[[long* pLeft]], "pointer" --[[long* pTop]], "pointer" --[[long* pWidth]], "pointer" --[[long* pHeight]]};
  {name="HideCursor"; "long"};
  {name="IsCursorHidden"; "pointer" --[[long* CursorHidden]]};
}

IMediaEvent = com.IDispatch:extend{
  IID = "56a868b6-0ad4-11ce-b03a-0020af0ba770";
  name = "IMediaEvent";
  target = _M;
  {name="GetEventHandle"; "pointer" --[[OAEVENT *hEvent]]};
  {name="GetEvent"; "pointer" --[[long *lEventCode]], "pointer" --[[LONG_PTR *lParam1]],
    "pointer" --[[LONG_PTR *lParam2]], "long" --[[msTimeout]]};
  {name="WaitForCompletion"; "long" --[[msTimeout]], "pointer" --[[long *pEvCode]]};
  {name="CancelDefaultHandling"; "long" --[[lEvCode]]};
  {name="RestoreDefaultHandling"; "long" --[[lEvCode]]};
  {name="FreeEventParams"; "long" --[[lEvCode]], "long" --[[LONG_PTR lParam1]], "long" --[[LONG_PTR lParam2]]};
}

IPin = com.IUnknown:extend{
  IID = "56a86891-0ad4-11ce-b03a-0020af0ba770";
  name = "IPin";
  target = _M;
  {name="Connect"; "pointer" --[[IPin*]], "pointer" --[[const AM_MEDIA_TYPE*]]};
  {name="ReceiveConnection"; "pointer" --[[IPin*]], "pointer" --[[const AM_MEDIA_TYPE*]]};
  {name="Disconnection"};
  {name="ConnectedTo"; "pointer" --[[IPin**]]};
  {name="ConnectionMediaType"; "pointer" --[[AM_MEDIA_TYPE*]]};
  {name="QueryPinInfo"; "pointer" --[[PIN_INFO*]]};
  {name="QueryDirection"; "pointer" --[[PIN_DIRECTION*]]};
  {name="QueryId"; "pointer" --[[LPWSTR *Id]]};
  {name="QueryAccept"; "pointer" --[[const AM_MEDIA_TYPE *pmt]]};
  {name="EnumMediaTypes"; "pointer" --[[IEnumMediaTypes**]]};
  {name="QueryInternalConnections"; "pointer" --[[IPin**]], "pointer" --[[ULONG*]]};
  {name="EndOfStream"};
  {name="BeginFlush"};
  {name="EndFlush"};
  {name="NewSegment"; "long" --[[REFERENCE_TIME tStart]], "long" --[[REFERENCE_TIME tStop]], "double" --[[dRate]]};
}

IID_IGraphBuilder = wincommon.MAKE_GUID(0x56A868A9, 0x0AD4, 0x11CE, 0xB0, 0x3A, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70)
IID_IMediaControl = wincommon.MAKE_GUID(0x56A868B1, 0x0AD4, 0x11CE, 0xB0, 0x3A, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70)
IID_IVideoWindow  = wincommon.MAKE_GUID(0x56a868b4, 0x0AD4, 0x11CE, 0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70)
IID_IMediaEvent   = wincommon.MAKE_GUID(0x56a868b6, 0x0ad4, 0x11ce, 0xb0, 0x3a, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70)
IID_IMediaEventEx = wincommon.MAKE_GUID(0x56a868c0, 0x0ad4, 0x11ce, 0xb0, 0x3a, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70)
CLSID_FilterGraph = wincommon.MAKE_GUID(0xE436EBB3, 0x524F, 0x11CE, 0x9F, 0x53, 0x00, 0x20, 0xAF, 0x0B, 0xA7, 0x70)

OATRUE = -1 
OAFALSE = 0

PINDIR_INPUT	= 0
PINDIR_OUTPUT	= PINDIR_INPUT + 1

State_Stopped = 0
State_Paused = 1
State_Running = 2
